package ms.maplestory.boot.loaders;

import ms.maplestory.boot.ServerConstants;
import ms.maplestory.boot.util.Util;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

@Slf4j(topic = "[Loader Main]")
public class MainLoader {

    private static ExecutorService loaderThreadPool;
    public static List<Class> data = new ArrayList<>();
    public static List<Class> datCreators = new ArrayList<>();
    public static boolean INFO_OUT = false;


    static {
        data.addAll(Arrays.asList(
                ItemData.class,
                SkillData.class,
                FieldData.class
        ));
        datCreators.addAll(Arrays.asList(
                FieldData.class,
                ItemData.class,
                MobData.class,
                NpcData.class,
                QuestData.class,
                ReactorData.class,
                SkillData.class,
                StringData.class,
                EtcData.class
        ));
    }

    public static void main(String[] args) {
        Set<Class> datCreators = new HashSet<>(MainLoader.datCreators);
        loaderThreadPool = Executors.newFixedThreadPool(datCreators.size());
        List<Callable<Object>> todo = new ArrayList<>(datCreators.size());
        Util.makeDirIfAbsent(ServerConstants.DAT_DIR);
        for (Class c : datCreators) {
            todo.add(Executors.callable(() -> {
                try {
                    log.info("Loader Thread: {}", Thread.currentThread().getName());
                    Method m = c.getMethod("generateDatFiles");
                    m.invoke(null);
                } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                    e.printStackTrace();
                }
            }));
        }
        try {
            List<Future<Object>> answers = loaderThreadPool.invokeAll(todo);
            log.info("Loaders Over!");
            System.exit(0);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
